import org.junit.Test;

import static org.junit.Assert.assertEquals;

public class SolverTest {

    @Test
    public void testSolverUnsolvableTwinned() {
        test(0, "puzzle3x3-unsolvable.txt", false);
    }

    @Test
    public void testSolver0() {
        test(0);
    }

    @Test
    public void testSolver1() {
        test(1);
    }

    @Test
    public void testSolver2() {
        test(2);
    }

    @Test
    public void testSolver3() {
        test(3);
    }

    @Test
    public void testSolver4() {
        test(4);
    }

    @Test
    public void testSolver5() {
        test(5);
    }

    @Test
    public void testSolver6() {
        test(6);
    }

    @Test
    public void testSolver7() {
        test(7);
    }

    @Test
    public void testSolver8() {
        test(8);
    }

    @Test
    public void testSolver9() {
        test(9);
    }

    @Test
    public void testSolver10() {
        test(10);
    }

    @Test
    public void testSolver11() {
        test(11);
    }

    @Test
    public void testSolver12() {
        test(12);
    }

    @Test
    public void testSolver13() {
        test(13);
    }

    @Test
    public void testSolver14() {
        test(14);
    }

    @Test
    public void testSolver15() {
        test(15);
    }

    @Test
    public void testSolver16() {
        test(16);
    }

    @Test
    public void testSolver17() {
        test(17);
    }

    @Test
    public void testSolver18() {
        test(18);
    }

    @Test
    public void testSolver19() {
        test(19);
    }

    @Test
    public void testSolver20() {
        test(20);
    }




    @Test
    public void testSolver17Up() {
        for (int i = 17; i < 46; i++) {
            test(i);

        }
    }

    private void test(int i) {
        String fileName = "";
        test(i, fileName, true);
    }

    private void test(int i, String fileName, boolean solvable) {
        if (fileName.length() > 0) {
            fileName = "puzzleExamples/" + fileName;
        } else if (i < 10) {
            fileName = "puzzleExamples/puzzle0" + i + ".txt";
        } else {
            fileName = "puzzleExamples/puzzle" + i + ".txt";
        }
        In in = new In(fileName);
        int N = in.readInt();
        int[][] goal = new int[N][N];
        int goalCounter = 1;
        int[][] blocks = new int[N][N];
        for (int j = 0; j < N; j++) {
            for (int k = 0; k < N; k++) {
                blocks[j][k] = in.readInt();
                if (j == N - 1 && k == N - 1) {
                    goal[j][k] = 0;
                } else {
                    goal[j][k] = goalCounter++;
                }
            }
        }
        Board initial = new Board(blocks);
        Board goalBoard = new Board(goal);

        // solve the puzzle
        Solver solver = new Solver(initial);
        assertEquals(solvable, solver.isSolvable());

        if (!solvable) {
            assertEquals(null, solver.solution());
        } else {
            int counter = 0;
            Board testBoard = null;
            for (Board board : solver.solution()) {
                testBoard = board;
                counter++;
            }
            assertEquals(goalBoard, testBoard);
        }
        if (solvable)
            assertEquals(i, solver.moves());
    }

}